package com.duoduo.commonn.redis.myinterface;


import com.duoduo.common.api.spi.extension.SPI;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**redis缓存实现
 * @author duoduo
 *
 */
@SPI
public interface RedisOperator {

	/**
     * 尝试获取分布式锁，直接使用RedisUtil实现
     * @param appName
     * @param lockKey
     * @param requestId
     * @param expireMsTime 有效期，单位毫秒
     * @return
     */
	boolean setNxPx(String redisKey, String appName, String lockKey, String requestId, long expireMsTime);

	/**
	 * 尝试获取分布式锁，直接使用RedisUtil实现
	 * @param appName
	 * @param lockKey
	 * @param requestId
	 * @param expireMsTime 有效期，单位毫秒
	 * @return
	 */
	<T extends Serializable> boolean setNxPxImplSeri(String redisKey, String appName, String key, T value, long expireMsTime);

	/**执行lur脚本
	 * @param appName
	 * @param script
	 * @param keys
	 * @param params
	 * @return
	 */
	Object eval(String redisKey, String appName, String script, List<String> keys, List<String> params);

	Object evalByte(String redisKey, String appName, String script, List<String> keys, List<byte[]> params);
	
	String get(String redisKey, String appName, String key);

	List<String> mget(String redisKey, String appName, String[] keys);
	
	<T extends Serializable> T getObjImplSeri(String redisKey, String appName, String key, Class<T> clazz);
	
	Boolean exists(String redisKey, String appName, String key);
	
	Boolean existsSeri(String redisKey, String appName, String key);

	/**加入key存在，返回key同时删除；不存在返回null
	 * @param appName
	 * @param key
	 * @return
	 */
	Object pop(String redisKey, String appName, String key);

	Long delKey(String redisKey, String appName, String key);
	
	String set(String redisKey, String appName, String key, String value, int expire);

	<T extends Serializable> String setImplSeri(String redisKey, String appName, String key, T value, int expire);

	long incr(String redisKey, String appName, String key);
	
	long decr(String redisKey, String appName, String key);
	
	/**如果key不存在，设置key并设置过期时间；如果key存在，检查key、value是否匹配，是就重置过期时间
	 * @param appName
	 * @param key
	 * @param value
	 * @param expire 有效期，单位秒
	 * @return 1：key不存在，设置成功；-1：key存在，并且key、value和传入的参数不匹配；2：key存在，并且key、value和传入的参数匹配，重入
	 */
	Object setNxAndResetTTL(String redisKey, String appName, String key, String value, int expire);

	Long addWithSortedSet(String redisKey, String appName, String key, double score, String member);

	Long zrem(String redisKey, String appName, String key, Collection<String> members);

	Set<String> rangeByScoreWithSortedSet(String redisKey, String appName, String key, double max, double min, int offset, int count);

	Long hincrBy(String prefixName, String appName, String key, String field, Long value);
	
	/**
     * 将哈希表 key中的域field的值设为 value.<br>
     * 如果key不存在,将新建一个哈希表.<br>
     * 如果域field已经存在于哈希表中,旧值将被覆盖.<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @param field 域
     * @param value value
     * @return 如果field是哈希表中的一个新建域,并且值设置成功,返回 1. 如果哈希表中域field已经存在且旧值已被新值覆盖,返回 0.
     */
	Long hashSet(String redisKey, String appName, String key, String field, String value);

	/**
     * 将哈希表 key中的域field的值设为 value,同时设置哈希表key的有效期.<br>
     * 如果key不存在,将新建一个哈希表.<br>
     * 如果域field已经存在于哈希表中,旧值将被覆盖.<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @param field 域
     * @param value value
     * @param expire 有效期（秒）
     * @return 如果field是哈希表中的一个新建域,并且值设置成功,返回 1.如果哈希表中域field已经存在且旧值已被新值覆盖,返回 0.异常返回null
     */
	Long hashSet(String redisKey, String appName, String key, String field, String value, int expire);
	
	/**
     * 返回哈希表key中给定域 field的值.<br>
     * 时间复杂度:O(1)
     *
     * @param key key
     * @param field 域
     * @return 给定域的值.当给定域不存在或是给定 key不存在时,返回 nil .
     */
    String hashGet(String redisKey, String appName, String key, String field);

	<T extends Serializable> Long hashSetImplSeri(String redisKey, String appName, String key, String field, T value);

	<T extends Serializable> Long hashSetImplSeri(String redisKey, String appName, String key, String field, T value, int expire);
	
	<T extends Serializable> T hashGetImplSeri(String redisKey, String appName, String key, String field, Class<T> clazz);

	Map<String, String> hashGetAll(String redisKey, String appName, String key);

	<T extends Serializable> Map<String, T> hashGetAllImplSeri(String redisKey, String appName, String key, Class<T> clazz);

	Long listPushTail(String redisKey, String appName, String key, String... values);
	
	@SuppressWarnings("unchecked")
	<T extends Serializable> Long listPushTailImplSeri(String redisKey, String appName, String key, T... values);

	Long listPushHead(String redisKey, String appName, String key, String... values);
	
	@SuppressWarnings("unchecked")
	<T extends Serializable> Long listPushHeadImplSeri(String redisKey, String appName, String key, T... values);
	
	String listPop(String redisKey, String appName, String key);
	
	<T extends Serializable> T listPopImplSeri(String redisKey, String appName, String key, Class<T> clazz);
	
}
